package com.itheima.stock.service.impl;

import com.alibaba.excel.EasyExcel;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.gson.Gson;
import com.itheima.stock.common.domain.StockExcelDomain;
import com.itheima.stock.common.domain.StockInfoConfig;
import com.itheima.stock.common.enums.ResponseCode;
import com.itheima.stock.job.service.StockTimerService;
import com.itheima.stock.mapper.StockBlockRtInfoMapper;
import com.itheima.stock.mapper.StockBusinessMapper;
import com.itheima.stock.mapper.StockMarketIndexInfoMapper;
import com.itheima.stock.mapper.StockRtInfoMapper;
import com.itheima.stock.pojo.StockBusiness;
import com.itheima.stock.service.StockService;
import com.itheima.stock.utils.DateTimeUtil;
import com.itheima.stock.utils.JosnJX;
import com.itheima.stock.vo.resp.PageResult;
import com.itheima.stock.vo.resp.R;
import com.itheima.stock.vo.resp.SecondResVo;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author by itheima
 * @Date 2021/12/19
 * @Description
 */
@Service("stockService")
public class StockServiceImpl implements StockService {
    @Autowired
    private StockBusinessMapper stockBusinessMapper;

    @Autowired
    private StockMarketIndexInfoMapper stockMarketIndexInfoMapper;

    @Autowired
    private StockInfoConfig stockInfoConfig;
    @Autowired
    private StockTimerService stockTimerService;

    @Autowired
    private StockBlockRtInfoMapper stockBlockRtInfoMapper;
    @Autowired
    private StockRtInfoMapper stockRtInfoMapper;
    @Override
    public R<List<Map>> getStockSecond(String code) throws IOException {
        String tDate = DateTimeUtil.getLastDateString4Stock(DateTime.now());
        String x = tDate.substring(0, 8);
        String url = "https://img1.money.126.net/data/hs/time/today/1399001.json";
        String a = JosnJX.getJSONData(url);
        String b = a.substring(71);
        String[] b1 = b.split("\\[");
        List<Map> list = new ArrayList<>();
        for (String c : b1) {
            Map<String, String> map = new HashMap<>();
            String d = c.replaceAll("\\]", "");
            String d1 = d.replaceAll("\"", "");
            String[] d2 = d1.split(",");
            String day = x + d2[0];
            map.put("date", day);
            map.put("tradeAmt", d2[3]);
            String i = Double.valueOf(d2[3]) * Double.valueOf(d2[1]) + "";
            map.put("tradeVol", i);
            map.put("tradePrice", d2[1]);
            list.add(map);
        }
        List<Map> list1 = new ArrayList<>();
        for (int i = 1; i <= 10; i++) {
            list1.add(list.get(list.size() - i));
        }
        return  R.ok(list1);

//        List<SecondResVo> stockRtInfoInTime = stockTimerService.getStockRtInfoInTime(code);
//        Collections.sort(stockRtInfoInTime, new Comparator<SecondResVo>() {
//            @Override
//            public int compare(SecondResVo o1, SecondResVo o2) {
//
//                return o2.getDate().compareTo(o1.getDate());
//            }
//        });
//        List<SecondResVo> secondResVos = stockRtInfoInTime.subList(0, 9);
//        return R.ok(secondResVos);


    }

    /**
     * 个股最新分时行情
     * @param code
     * @return
     */
    @Override
    public R<Map> getrealTimeNow(String code) {

        //获取当前时间
        String stock = DateTimeUtil.getLastDateString4Stock(DateTime.now());
        Map info=stockRtInfoMapper.getrealTimeNow(code,stock);
        if (CollectionUtils.isEmpty(info)) {
            return R.error("暂无数据");
        }
        return R.ok(info);
    }

    @Override
    public R<Map> getStockBusinessShow(String stockCode) {
        Map maps = this.stockBusinessMapper.getStockBusinessShow(stockCode);
        //设置
        if (CollectionUtils.isEmpty(maps)){
            return R.error("暂时没有数据");
        }
        return R.ok(maps);
    }

    @Override
    public List<StockBusiness> getAllStockBusiness() {
        return stockBusinessMapper.getAll();
    }
    /**
     * 周k
     * @param code
     * @return
     */
    @Override
    public R<List<Map>> getweeklyChart(String code) {
        List<Map>result=stockRtInfoMapper.getLineGraph(code);
        return R.ok(result);
    }

    /**
     * 联想查询
     * @param searchStr
     * @return
     */
    @Override
    public R<List<Map>> getlimitBusiness(String searchStr) {
        //查询、、查询到返回给web，没有返回莫得数据
        List<String>limitAll=stockRtInfoMapper.getLimitGuPiao(searchStr);
        ArrayList<Map> list = new ArrayList<>();
        for (int i = 0; i < limitAll.size(); i++) {
            String name=stockRtInfoMapper.getname(limitAll.get(i));
            HashMap<String, String> hashMap = new HashMap<>();
            hashMap.put("code",limitAll.get(i));
            hashMap.put("name",name);
            list.add(hashMap);
        }

        if (CollectionUtils.isEmpty(limitAll)) {
            return R.error("莫得数据");
        }
        return R.ok(list);
    }
    @Override
    public R<List<Map>> getInnerStockMarket() {
//        //获取最近股票有效交易日，精确到分钟
//        String lastAvDate = DateTimeUtil.getLastDateString4Stock(DateTime.now());
//        //设置成有效数据（数据库测试数据可能不存在）
//          //lastAvDate="20211228095300";
//        List<Map> infos = stockMarketIndexInfoMapper.getInnerStockMarket(stockInfoConfig.getInner(), lastAvDate);
//        if (CollectionUtils.isEmpty(infos)) {
//            return R.error("暂无数据");
//        }
//        return R.ok(infos);
        //1.获取国内大盘的id集合
        List<String> innerIds = stockInfoConfig.getInner();
        //2.获取最近最新的股票有效交易日
        DateTime lDate = DateTimeUtil.getLastDate4Stock(DateTime.now());
        String mockDate="20211226105600";//TODO 后续大盘数据实时拉去，将该行注释掉 传入的日期秒必须为O
        Date date = DateTime.parse(mockDate, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
        //3.调用mapper查询指定日期下对应的国内大盘数据
        List<Map> maps=stockMarketIndexInfoMapper.selectByIdsAndDate(innerIds,date);
        //组装响应的额数据
        if (CollectionUtils.isEmpty(maps)) {
            return R.error(ResponseCode.NO_RESPONSE_DATA.getMessage());
        }
        return R.ok(maps);
    }

    @Override
    public R<List<Map>> getSectorAllLimit() {
        List<Map> maps = stockBlockRtInfoMapper.getSectorAllLimit();
        if (CollectionUtils.isEmpty(maps)) {
            return R.error("暂时没有数据");
        }
        return R.ok(maps);
    }

    @Override
    public R<List<Map>> getStockIncrease() {
        List<Map> maps = stockRtInfoMapper.getStockIncrease();
        if (CollectionUtils.isEmpty(maps)) {
            return R.error("暂时没有数据！");
        }
        return R.ok(maps);
    }

    @Override
    public R<PageResult> getStockAll(Integer page, Integer pageSize) {
        //设置分页参数
        PageHelper.startPage(page, pageSize);
        //查询
        List<Map> maps = this.stockRtInfoMapper.getStockAll();
        if (CollectionUtils.isEmpty(maps)) {
            return R.error("暂无数据");
        }
        PageInfo<Map> pageInfo = new PageInfo<>(maps);
        PageResult<Map> pageResult = new PageResult<>(pageInfo);
        return R.ok(pageResult);
    }

    @Override
    public R<Map> getStockUpDownLimitCount() {
//        //获取涨停统计数
//        List<Map> upLimit = this.stockRtInfoMapper.getUpDownLimitCount(1);
//        String curDate = DateTime.now().toString(DateTimeFormat.forPattern("yyyyMMddHHmm"));
//        //curDate="20211228095300";
//        if (CollectionUtils.isEmpty(upLimit)) {
//            //设置默认值
//            HashMap<String, Object> map = new HashMap<>();
//            map.put("time", curDate);
//            map.put("count", 0);
//            upLimit.add(map);
//        }
//        //获取跌停统计数
//        List<Map> downLimit = this.stockRtInfoMapper.getUpDownLimitCount(0);
//        if (CollectionUtils.isEmpty(upLimit)) {
//            //设置默认值
//            HashMap<String, Object> map = new HashMap<>();
//            map.put("time", curDate);
//            map.put("count", 0);
//            downLimit.add(map);
//        }
//        //组装数据
//        HashMap<String, List<Map>> map = new HashMap<>();
//        map.put("upList", upLimit);
//        map.put("downList", downLimit);
//        return R.ok(map);
        DateTime curDateTime = DateTimeUtil.getLastDate4Stock(DateTime.now());
        //当前最近有效期
        Date curTime = curDateTime.toDate();
        //开盘日期
        Date openTime = DateTimeUtil.getOpenDate(curDateTime).toDate();
        //TODO 后续数据实时获取时，注释掉
        String curTimeStr="20220106142500";
        //对应开盘日期
        String openTimeStr="20220106092500";
        curTime = DateTime.parse(curTimeStr, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
        try {
            curTime=new SimpleDateFormat("yyyyMMddHHmmss").parse(curTimeStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        openTime = DateTime.parse(openTimeStr, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
        try {
            openTime=new SimpleDateFormat("yyyyMMddHHmmss").parse(openTimeStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        //2.统计涨停的数据 约定：1代表涨停 0：跌停
        List<Map> upCount= stockRtInfoMapper.upDownCount(curTime,openTime,1);
        //3.统计跌停的数据
        List<Map> downCount= stockRtInfoMapper.upDownCount(curTime,openTime,0);
        //4.组装数据到map
        HashMap<String, List<Map>> info = new HashMap<>();
        info.put("upList",upCount);
        info.put("downList",downCount);
        //5.响应
        return R.ok(info);
    }

    @Override
    public void exportStockExcel(HttpServletResponse response, Integer page, Integer pageSize) {
        try {
            //设置响应数据格式
            response.setContentType("application/vnd.ms-excel");
            //设置编码
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("stockRt", "UTF-8");
            //设置默认文件名称
            response.setHeader("content-disposition", "attachment;filename=" + fileName + ".xlsx");
            //获取导出的分页数据
            PageHelper.startPage(page, pageSize);
            List<Map> maps = this.stockRtInfoMapper.getStockAll();
            List<StockExcelDomain> domains = new ArrayList<>();
            //转化成StockExcelDomain对象
            Gson gson = new Gson();
            maps.forEach(row -> {
                StockExcelDomain domain = gson.fromJson(gson.toJsonTree(row), StockExcelDomain.class);
                domains.add(domain);
            });
            EasyExcel.write(response.getOutputStream(), StockExcelDomain.class)
                    .sheet("stockRt").doWrite(domains);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public R<Map> getStockTravolCompare() {
//        DateTime target = DateTimeUtil.getLastDate4Stock(DateTime.now());
//        //转string
//        String curTStr = DateTimeUtil.parseToString4Stock(target);
//        //curTStr="20220103133000";
//        //T-1的日期数据
//        String preTStr = DateTimeUtil.parseToString4Stock(DateTimeUtil.getPreviousTradingDay(target));
//        //preTStr="20220102133000";
//        //获取T日成交量数据
//        List<Map> nowDatas = this.stockMarketIndexInfoMapper.getStockTravol(curTStr);
//        if (CollectionUtils.isEmpty(nowDatas)) {
//            nowDatas = Collections.emptyList();
//        }
//        //获取T-1数据
//        List<Map> preDatas = this.stockMarketIndexInfoMapper.getStockTravol(preTStr);
//        if (CollectionUtils.isEmpty(preDatas)) {
//            preDatas = Collections.emptyList();
//        }
//        //组装数据
//        HashMap<String, List> map = new HashMap<>();
//        map.put("volList", nowDatas);
//        map.put("yesVolList", preDatas);
//        return R.ok(map);
        DateTime tDate = DateTimeUtil.getLastDate4Stock(DateTime.now());
        Date tDateTime = tDate.toDate();
        //对应的开盘时间
        Date tOpenTime = DateTimeUtil.getOpenDate(tDate).toDate();
        //TODO 后续注释掉
        String tDateStr="20220103143000";
        tDateTime = DateTime.parse(tDateStr, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
        String openDateStr="20220103093000";
        tOpenTime = DateTime.parse(openDateStr, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();

        //获取T-1交易日
        DateTime preTDate = DateTimeUtil.getPreviousTradingDay(tDate);
        Date preTTime = preTDate.toDate();
        Date preTOpenTime=DateTimeUtil.getOpenDate(preTDate).toDate();
        //TODO 后续注释掉
        String preTStr="20220102143000";
        preTTime = DateTime.parse(preTStr, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
        String openDateStr2="20220102093000";
        preTOpenTime= DateTime.parse(openDateStr2, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();

        //2.获取T日的股票大盘交易量统计数据
        List<Map> tData=stockMarketIndexInfoMapper.stockTradeVolCount(stockInfoConfig.getInner(),tOpenTime,tDateTime);
        //3.获取T-1的数据
        List<Map> preTData=stockMarketIndexInfoMapper.stockTradeVolCount(stockInfoConfig.getInner(),preTOpenTime,preTTime);
        //4.组装数据
        HashMap<String, List<Map>> data = new HashMap<>();
        data.put("volList",tData);
        data.put("yesVolList",preTData);
        return R.ok(data);
    }

    @Override
    public R<Map> getStockUpDownScope() {
//        //1.获取最近的有效股票交易时间，精确到分钟
//        DateTime target = DateTimeUtil.getLastDate4Stock(DateTime.now());
//        String last = DateTimeUtil.getLastDateString4Stock(target);
//        // 模拟数据
//        //last = "20220106095500";
//        //2.查询数据库,统计个股的涨跌幅
//        List<Map> maps = stockRtInfoMapper.getStockUpDownScope(last);
//        if (CollectionUtils.isEmpty(maps)) {
//            maps = Collections.emptyList();
//        }
//        // 处理查询结果数据,将无序的涨幅区间变为有序的,如果当前区间内没有数据则填充 0
//        //a.获取配置文件中涨幅区间标记
//        List<String> upDownRange = stockInfoConfig.getUpDownRange();
//        // 将集合中的数据进行转换 // key: "<-7%" "-7~-5%" ....
//        List<Map> finalMaps = maps;
//        List<Map> newInfos = upDownRange.stream().map(key -> {
//            // 对查询结果进行过滤
//            Optional<Map> title = finalMaps.stream().filter(map -> key.equals(map.get("title"))).findFirst();
//            Map map = null;
//            //判定title是否存在,如果存在则说明当前范围内有个股数据
//            if (title.isPresent()) {
//                map = title.get();
//            } else {
//                map = new HashMap();
//                map.put("title", key);
//                map.put("count", 0);
//            }
//            return map;
//        }).collect(Collectors.toList());
//
//        //3.封装响应结果数据
//        HashMap<String, Object> map = new HashMap<>();
//        map.put("time", target.toString("yyyy-MM-dd HH:mm:ss"));
//        map.put("infos", newInfos);
//        return R.ok(map);
        //1.获取当前时间下最近的一个股票交易时间 精确到秒
        DateTime avlDateTime = DateTimeUtil.getLastDate4Stock(DateTime.now());
        Date avlDate = avlDateTime.toDate();
        //TODO 后续删除
        String  mockDate="20220106095500";
        avlDate = DateTime.parse(mockDate, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
        //2.查询
        List<Map> maps=stockRtInfoMapper.stockUpDownScopeCount(avlDate);
        //获取去股票涨幅区间的集合
        List<String> upDownRange = stockInfoConfig.getUpDownRange();
        ArrayList<Map> orderMap = new ArrayList<>();
        for (String title : upDownRange) {
            Map tmp=null;
            for (Map map : maps) {
                if (title.equals(map.get("title"))) {
                    tmp=map;
                }
            }
            if (tmp==null) {
                tmp=new HashMap();
                tmp.put("title",title);
                tmp.put("count",0);
            }
            orderMap.add(tmp);
        }
        //3.组装data
        HashMap<String, Object> data = new HashMap<>();
        data.put("time",avlDateTime.toString("yyyy-MM-dd HH:mm:ss"));
        data.put("infos",orderMap);
        //返回响应数据
        return R.ok(data);
    }

    @Override
    public R<List<Map>> getStockScreenMinuteSharing(String stockCode) {
//        String tDate = DateTimeUtil.getLastDateString4Stock(DateTime.now());
//        // tDate="20220106095500";
//        //查询
//        List<Map> infos = this.stockRtInfoMapper.getStockScreenMinuteSharing(stockCode, tDate);
//        if (CollectionUtils.isEmpty(infos)) {
//            return R.error("暂无数据");
//        }
//        return R.ok(infos);
        //1.获取最近有效的股票交易时间
        DateTime curDateTime = DateTimeUtil.getLastDate4Stock(DateTime.now());
        //获取当前日期
        Date curDate = curDateTime.toDate();
        //获取当前日期对应的开盘日期
        Date openDate = DateTimeUtil.getOpenDate(curDateTime).toDate();

        //TODO 后续删除
        String mockDate="20220106142500";
        curDate=DateTime.parse(mockDate, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
        String openDateStr="20220106093000";
        openDate=DateTime.parse(openDateStr, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();

        List<Map> maps= stockRtInfoMapper.stockScreenTimeSharing(stockCode,openDate,curDate);
        //响应前端
        return R.ok(maps);
    }

    @Override
    public R<List<Map>> getDayKLinData(String code) {
//        DateTime hisDate = DateTime.now().minusDays(20);
//        //获取日期字符串
//        String hisDateStr = hisDate.toString(DateTimeFormat.forPattern("yyyyMMdd"));
//        //hisDateStr="20211201";
//        List<Map> infos = stockRtInfoMapper.getDayKLinData(stockCode, hisDateStr);
//        if (CollectionUtils.isEmpty(infos)) {
//            return R.error("暂无数据");
//        }
//        return R.ok(infos);
        DateTime curDateTime = DateTimeUtil.getLastDate4Stock(DateTime.now());
        //当前时间节点
        Date curTime = curDateTime.toDate();
        //前推20
        Date pre20Day = curDateTime.minusDays(20).toDate();

        //TODO 后续删除
        String avlDate="20220106142500";
        curTime=DateTime.parse(avlDate, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();
        String openDate="20220101093000";
        pre20Day=DateTime.parse(openDate, DateTimeFormat.forPattern("yyyyMMddHHmmss")).toDate();

        //获取指定范围的收盘日期集合
        List<Date> closeDates=stockRtInfoMapper.getCloseDates(code,pre20Day,curTime);
        //根据收盘日期精准查询，如果不在收盘日期，则查询最新数据
        List<Map> data= stockRtInfoMapper.getStockCreenDkLineData(code,closeDates);
        return R.ok(data);
    }

    @Override
    public R<List<Map>> getForeignMarket() {
        //获取最近股票有效交易日，精确到分钟
        String lastAvDate = DateTimeUtil.getLastDateString4Stock(DateTime.now());
        DateTimeFormatter dateTimeFormatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
        DateTime dateTime = dateTimeFormatter.parseDateTime(lastAvDate);
        Date date = dateTime.toDate();
        //设置成有效数据（数据库测试数据可能不存在）
        //lastAvDate="20211228095300";
        List<Map> infos = stockMarketIndexInfoMapper.getourStockMarket(stockInfoConfig.getOuter(),date);
        if (CollectionUtils.isEmpty(infos)) {


                return R.error("暂无数据");

        }
        return R.ok(infos);
    }
}
